package com.itheima.service.impl;



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.Category;
import com.itheima.bean.Dish;
import com.itheima.bean.DishFlavor;
import com.itheima.common.PageParam;
import com.itheima.dao.DishDao;
import com.itheima.dto.DishDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;


@Service
@Transactional
public class DishServiceImpl implements DishService {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private DishDao dishDao;

    @Override
    public List<DishDto> findByCategoryId(Long categoryId, Integer status) {
        //1. 构建条件对象
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //2. 设置条件
        lqw.eq(Dish::getCategoryId, categoryId);
        lqw.eq(status!=null,Dish::getStatus,status);
        //执行结果
        List<Dish> dishList = dishDao.selectList(lqw);
        //把dish装进Dto中
        return dishList.stream().map(dish -> {
            DishDto dto = new DishDto();
            //拷贝
            BeanUtils.copyProperties(dish,dto);

            //设置剩下的数据
            // 先查找 在遍历  根据dishID找口味 设置到扩展类中
            List<DishFlavor> flavorList = dishFlavorService.findByDishId(dish.getId());
            dto.setFlavors(flavorList);
            //返回扩展类
            return dto;

        }).collect(Collectors.toList());

    }

    @Override
    public int add(DishDto dishDto) {
        //1. 添加到菜品表
        int row = dishDao.insert(dishDto);


        // 2. 添加到口味表

        //2.1 获取菜品的口味数据
        List<DishFlavor> flavorList = dishDto.getFlavors();
        int row2 = 0;
        if (flavorList != null && flavorList.size() > 0) {
            //2.2遍历集合

            for (DishFlavor dishFlavor : flavorList) {
                //设置是属于那个菜品
                dishFlavor.setDishId(dishDto.getId());

                //添加到口味列表里
                row2 += dishFlavorService.add(dishFlavor);

            }
        }

        return row > 0 && row2 == flavorList.size() ? 1 : 0;
    }

    @Override
    public IPage<DishDto> findPage(PageParam pageParam) {

        //定义分页对象
        Page<Dish> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());

        //设置条件对象
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();

        //设置条件
        lqw.like(pageParam.getName() != null, Dish::getName, pageParam.getName());

        // 执行查询
        Page<Dish> dishPage = dishDao.selectPage(page, lqw);

        //4.构建IPage<DishDto>
        Page<DishDto> dishDtoPage = new Page<>();

        //4.1设置总记录数
        dishDtoPage.setTotal(dishPage.getTotal());

        //4.2 构建出来List<DishDto> ， 才可以装到dishDtoPage里面
        List<DishDto> collect = dishPage.getRecords().stream().map(dish -> {
            //构建新的DishDto
            DishDto dishDto = new DishDto();

            //把dish本身的东西放到 dishDto中
            BeanUtils.copyProperties(dish, dishDto);

            // 设置分类的名称
            Category byId = categoryService.findById(dish.getCategoryId());
            dishDto.setCategoryName(byId.getName());

            return dishDto;

        }).collect(Collectors.toList());

        dishDtoPage.setRecords(collect);
        return dishDtoPage;


    }

    /**
     * 根据id查询菜品数据
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(long id) {
        //先查询dish数据
        Dish dish = dishDao.selectById(id);

        //在查询分类(属于哪一种的)数据
        Category category = categoryService.findById(dish.getCategoryId());
        //查询口味
        List<DishFlavor> byDishId = dishFlavorService.findByDishId(dish.getId());

        //构建dishDto
        DishDto dishDto = new DishDto();
        //将dish中的数据封装到扩展类dishDto中
        BeanUtils.copyProperties(dish, dishDto);
        //封装分类数据到dto中 dto中有对应的属性 直接设置就可
        dishDto.setCategoryName(category.getName());

        //封装口味到dto中
        dishDto.setFlavors(byDishId);
        return dishDto;
    }


    /**
     * 更新菜品
     * 1. 更新菜品和以前的更新不一样，因为它要操作两张表： 菜品表（dish） 和 口味表(dish_flavor)
     * 2. 先更新菜品表
     * 2.1 很简单，就按照原来的更新操作来执行即可
     * <p>
     * 3. 再更新口味表
     * 3.1 由于口味的更新的组合太多了，需要去计较的种类太多，太复杂。
     * 3.2 所以可以把口味表里面的原始口味数据删除掉 ，然后再把页面传递过来的口味数据添加进去。
     *
     * @param dishDto
     * @return
     */
    @Override
    public int update(DishDto dishDto) {
        //先更新菜品表
        int row = dishDao.updateById(dishDto);
        //把原来的口味删除
        dishFlavorService.deleteByDishId(dishDto.getId());

        //再把新的口味数据添加到表里面
        //先从dto中获取
        List<DishFlavor> flavors = dishDto.getFlavors();

        //判断是否有口味数据,如果有,就遍历髯口添加到口味表
        int row2 = 0;
        if (flavors.size() > 0) {
            for (DishFlavor flavor : flavors) {

                //设置口味数据属于哪个菜品 设置相对应的字段
                flavor.setDishId(dishDto.getId());
                //调用service添加
                row2 += dishFlavorService.add(flavor);
            }

        }
        return row > 0 && row2 == flavors.size() ? 1 : 0;
    }

    @Override
    public int delete(List<Long> ids) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();

        //设置条件
        lqw.eq(Dish::getStatus, 1);

        //执行查询
        Long aLong = dishDao.selectCount(lqw);

        if (aLong > 0) {
            throw new CustomException("此商品处于启售状态:禁止删除");
        }
        int row = dishDao.deleteBatchIds(ids);
        return row == ids.size() ? 1 : 0;
    }

    //批量停售
    @Override
    public void updateByState(int status,List<Long> ids) {
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();

        int a = 0;
        if (status==0){
            a=1;
        }
        //设置条件
        lqw.eq(Dish::getStatus,a);
        lqw.in(Dish::getId,ids);
        //执行查询
        List<Dish> dishList = dishDao.selectList(lqw);
        for (Dish dish : dishList) {
            dish.setStatus(status);
            dishDao.updateById(dish);
        }


    }
}
